home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 2324 / 2324.xpi / chrome / sessionmanager.jar / content / sessionmanager / sessionconvert.js < prev    next >
Encoding:
JavaScript  |  2009-05-04  |  28.5 KB  |  692 lines

  1. /*
  2.  * This file contains conversion routines for converting from SessionSaver and TMP session formats to
  3.  * Session Manager session format.  
  4.  * Portions of the following code as marked were originally written by onemen, rue and pike
  5.  */
  6.  
  7. /*
  8.  * Code to convert from SessionSaver 0.2 format to Session Manager format
  9.  * Original code by Morac except where indicated otherwise
  10.  */
  11. var gSessionSaverConverter = {
  12.     
  13.     sessionList: null,
  14.     sessions: null,
  15.     
  16.     exportFileExt: "ssv", exportFileMask: "*.ssv",
  17.     prefBranch:      'sessionsaver.',
  18.     prefBranchStatic:      'static.', // all manually captured sessions
  19.     prefBranchWindows:    'windows.', // the "live" capture of the current session
  20.     staticBranchDefault:  'default.', // the default manual-session
  21.     D : ["  ", "| "," |", " ||"], // new-style
  22.     
  23.     getEOL: function()
  24.     {
  25.         return /win|os[\/_]?2/i.test(navigator.platform)?"\r\n":/mac/i.test(navigator.platform)?"\r":"\n";
  26.     },
  27.     
  28.     init: function() {
  29.         this.prefService     = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefService);
  30.         this.rootBranch         = this.prefService.getBranch(null);
  31.         this.Branch             = this.prefService.getBranch(this.prefBranch);
  32.         this.staticBranch       = this.prefService.getBranch(this.prefBranch + this.prefBranchStatic);
  33.         this.windowBranch       = this.prefService.getBranch(this.prefBranch + this.prefBranchWindows);
  34.         
  35.         var windowMediator  = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator);
  36.         var chromeWin = windowMediator.getMostRecentWindow("navigator:browser");
  37.         this.gSessionManager = chromeWin.gSessionManager;
  38.         
  39.         // if encrypting, force master password and exit if not entered
  40.         try {
  41.             if (this.gSessionManager.mPref_encrypt_sessions) this.gSessionManager.mSecretDecoderRing.encryptString("");
  42.         }
  43.         catch(ex) {
  44.             this.gSessionManager.cryptError(gSessionManager._string("encrypt_fail2"));
  45.             this.prefService = null;
  46.             this.rootBranch = null;
  47.             this.Branch = null;
  48.             this.staticBranch = null;
  49.             this.windowBranch = null;
  50.             this.gSessionManager = null;
  51.             return;
  52.         }
  53.             
  54.         var aObj = {}, aObj2 = {}; 
  55.         this.staticBranch.getChildList("", aObj);
  56.         this.windowBranch.getChildList("", aObj2);
  57.         
  58.         if (aObj.value || aObj2.value) {
  59.             var okay = true;
  60.             var skip = false;
  61.             if ((this.Branch.getPrefType("SM_Converted") == 128) && 
  62.                  this.Branch.getBoolPref("SM_Converted")) {
  63.                 skip = true;
  64.                 if (this.confirm(this.gSessionManager._string("ss_convert_again"))) okay = false;
  65.                 
  66.             }
  67.             if (okay) {
  68.                 if (skip || !this.confirm(this.gSessionManager._string("ss_confirm_convert"))) {
  69.                     var data = this.createSessionData();
  70.                     this.findValidSession(data,true);
  71.                     this.Branch.setBoolPref("SM_Converted", true);
  72.                 }
  73.             }
  74.             
  75.             // check if SessionSaver installed and if so don't offer to delete data
  76.             if (!chromeWin.SessionSaver && !this.confirm(this.gSessionManager._string("ss_confirm_archive"))) {
  77.                 if (this.exportSession()) {
  78.                     try{ this.Branch.deleteBranch(""); } 
  79.                     catch(e) { this._prompt.alert(null,this.gSessionManager._string("sessionManager"), "Removed Fail: "+e); }
  80.                 }
  81.             }
  82.         }
  83.         else {
  84.             if (!this.confirm(this.gSessionManager._string("ss_confirm_import"))) this.importSession();
  85.         }
  86.         this.prefService = null;
  87.         this.rootBranch = null;
  88.         this.Branch = null;
  89.         this.staticBranch = null;
  90.         this.windowBranch = null;
  91.         this.gSessionManager = null;
  92.     },
  93.  
  94.     confirm: function (aMsg) {
  95.         var promptService = this._prompt;
  96.         return promptService.confirmEx(null,
  97.                                     this.gSessionManager._string("sessionManager"),
  98.                                     aMsg,
  99.                                     (promptService.BUTTON_TITLE_YES * promptService.BUTTON_POS_0)
  100.                                     + (promptService.BUTTON_TITLE_NO * promptService.BUTTON_POS_1),
  101.                                     null, null, null, null, {});
  102.     },
  103.     
  104.     get _prompt() {
  105.         return Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
  106.     },
  107.         
  108.     get _sessions() {
  109.         return gSessionSaverConverter.sessionList;
  110.     },
  111.     
  112.     convertSession: function(client, zHash) {
  113.         var i, j, m, SessionData = [], failedList = "\n";
  114.         for (m in zHash.asName) {
  115.             var name = zHash.asName[m];
  116.             var zorder = client[m + ".zorder"].split(",");
  117.             SessionData[name] = { cookies: (client[m + ".cookies"]?client[m + ".cookies"].split("  |"):null), windows:[] };
  118.             for (i in zorder) {
  119.                 if (zorder[i] && client[(m + "." + zorder[i])]) SessionData[name].windows[i] = client[(m + "." + zorder[i])];
  120.             }
  121.         }
  122.             
  123.         this.sessionList = [];
  124.         this.sessions = [];
  125.         for (i in SessionData) {
  126.             try {
  127.                 var windows = SessionData[i].windows;
  128.                 var totalTabCount = 0;
  129.                 var jsWindows = [];
  130.             
  131.                 for (j in windows) {
  132.                     var session = windows[j].split(this.D[0]); // get stored window-session from data
  133.                     if (session.length < 8) return;   // bad session data since no tabs so exit
  134.                 
  135.                     var win = { tabs:[], width: session[1], height: session[2], screenX: session[3],
  136.                                 screenY: session[4], selected: parseInt(session[6] + 1), 
  137.                                 sizemode: ((session[9]=="1")?"maximized":"normal"), _closedTabs:[] };
  138.  
  139.                     var chromeProperties = session[5].split("");
  140.                     var hidden = "";
  141.                     if (chromeProperties[0]=="0") win.hidden = win.hidden = "menubar"; 
  142.                     if (chromeProperties[1]=="0") win.hidden = win.hidden = ",toolbar"; 
  143.                     if (chromeProperties[2]=="0") win.hidden = win.hidden = ",locationbar";
  144.                     if (chromeProperties[3]=="0") win.hidden = win.hidden = ",personalbar";
  145.                     if (chromeProperties[4]=="0") win.hidden = win.hidden = ",statusbar"; 
  146.                     if (chromeProperties[5]=="0") win.hidden = win.hidden = ",scrollbars";
  147.                     if (hidden!="") win.hidden = hidden;
  148.                                 
  149.                     var tabCount = parseInt(session[7]);
  150.                     totalTabCount = totalTabCount + tabCount;
  151.                     var sessionTabs = session[8].split(this.D[3]);;
  152.                 
  153.                     var tabs = win.tabs;
  154.                     for (var k=0; k < tabCount; k++) {
  155.                         var tabData = { entries: [], index: 0 };
  156.                         this.convertTab(sessionTabs[k], tabData);
  157.                         tabs.push(tabData);
  158.                     }
  159.                 
  160.                     jsWindows.push(win);
  161.                 }
  162.                 
  163.                 if (jsWindows.length) {
  164.                     var cookies = SessionData[i].cookies;
  165.                     if (cookies) {
  166.                         var jsCookies = { count:0 };
  167.                         for (j in cookies) {
  168.                             var cookie = cookies[j].match(/^([^ ]+) (.+)$/);
  169.                             if ((cookie && cookie[1] && cookie[2])) {
  170.                                 jsCookies["domain" + ++jsCookies.count] = cookie[1];
  171.                                 jsCookies["value" + jsCookies.count] = cookie[2];
  172.                             }
  173.                         }
  174.                         jsWindows[0].cookies = jsCookies;
  175.                     }
  176.             
  177.                     this.sessions[i] = { windows: jsWindows, selectedWindow: 1 };
  178.             
  179.                     var sessionListItem = { name: i, fileName: i, autosave: false, windows: jsWindows.length, tabs: totalTabCount, group: "[SessionSaver]" };
  180.                     this.sessionList.push(sessionListItem);
  181.                 }
  182.                 else {
  183.                     failedList = failedList + "\n" + i;
  184.                 }
  185.             }
  186.             catch(ex) { 
  187.                 failedList = failedList + "\n" + i + " - " + ex;    
  188.             }
  189.         }
  190.         
  191.         if (failedList != "\n") {
  192.             this._prompt.alert(null,this.gSessionManager._string("sessionManager"), this.gSessionManager._string("ss_failed")+failedList);
  193.         }
  194.         
  195.         if (!this.sessionList.length) {
  196.             this._prompt.alert(null, this.gSessionManager._string("sessionManager"), this.gSessionManager._string("ss_none"));
  197.             return;
  198.         }
  199.         
  200.         var sessions = this.gSessionManager.selectSession(this.gSessionManager._string("ss_select"), this.gSessionManager._string("ss_convert"), 
  201.                                                           { multiSelect: true }, function() { return gSessionSaverConverter.sessionList;});
  202.         if (sessions) {
  203.             sessions = sessions.split("\n");
  204.             sessions.forEach(function (aSession) {
  205.                 var session = this.sessionList.filter(function(element,index,array) { return (element.name == aSession); });
  206.                 if (session.length) {
  207.                     var date = new Date();
  208.                     var aName = this.gSessionManager.getFormattedName("[ SessionSaver ] " + aSession, date);
  209.                     var file = this.gSessionManager.getSessionDir(this.gSessionManager.makeFileName(aName), true);
  210.                     var state = "[SessionManager v2]\nname=" + aName + "\ntimestamp=" + Date.now() + "\nautosave=false\tcount=" + 
  211.                                  session[0].windows + "/" + session[0].tabs + "\tgroup=[SessionSaver]\n" + 
  212.                                  this.gSessionManager.decryptEncryptByPreference(this.gSessionManager.JSON_encode(this.sessions[aSession]));
  213.                     this.gSessionManager.writeFile(file, state);
  214.                 }
  215.             }, this);
  216.         
  217.             this._prompt.alert(null,this.gSessionManager._string("sessionManager"),
  218.                   ((sessions.length>1)?this.gSessionManager._string("ss_converted_many"):this.gSessionManager._string("ss_converted_one"))+":\n\n. . ."+sessions.join("\n. . ."));
  219.         }
  220.         delete(this.sessionList);
  221.         delete(this.sessions);
  222.     },
  223.     
  224.     knownProps: {x:0,p:0,q:0,f:0,a:0,i:0,s:0,z:0},
  225.     contentTypeRe:   /^(Content-Type: )([^\r\n]+)((\r\n){1,2}|\r|\n)/m,  
  226.     contentLengthRe: /^(Content-Length: )([^\r\n]+)((\r\n){1,2}|\r|\n)/m,
  227.     
  228.     convertTab: function(sessionTab, tabData) {
  229.         // tab-properties
  230.         var tabSession  = sessionTab.split(this.D[2]); // XXX (below) for tabs with nothing captured (eg. link->newtab failed) there's nothing to iterate, so we need to check 'tabSession[propPoint-1]' as a condition
  231.         for (var propPoint=tabSession.length, propName;  tabSession[propPoint-1] && (propName=tabSession[propPoint-1].charAt(0));  propPoint--) if (propName=='z') break; else if (!propName in this.knownProps) tabSession.splice(propPoint++,1); // forwards-compatible, always
  232.         var postData    = (tabSession[0].charAt(0) == "p") ? tabSession.shift().slice(1) : null; // post-data,        if any (nightly 26)
  233.         var postDataII  = (tabSession[0].charAt(0) == "q") ? tabSession.shift().slice(1) : null; // post-data.ii,     if any (nightly 29)
  234.         if (postDataII) postData = postDataII;
  235.         var frameData   = (tabSession[0].charAt(0) == "f") ? tabSession.shift().slice(1) : null; // frame-data,     if any (nightly 27)
  236.         var selectData  = (tabSession[0].charAt(0) == "s") ? tabSession.shift().slice(1) : null; // select-data,    if any (nightly 28)
  237.         var inputData   = (tabSession[0].charAt(0) == "i") ? tabSession.shift().slice(1) : null; // input-data,     if any (nightly 28)
  238.         var areaData    = (tabSession[0].charAt(0) == "a") ? tabSession.shift().slice(1) : null; // textarea-data,  if any (nightly 28)
  239.         var propData    = (tabSession[0].charAt(0) == "x") ? tabSession.shift().slice(1) : null; // extra tab/docshell props, if any (nightly 29.iii)
  240.         if (tabSession[0].charAt(0) != "z") tabSession.splice(0, 0, "z1.0"); // add text-zoom if not stored (history-string will be in slot[1])
  241.         tabData.zoom    = parseFloat( tabSession[0].substr(1, tabSession.shift().length-1) ); // text-zoom (nightly 13)
  242.         var activeIndex = parseInt( tabSession.shift() );
  243.         tabData.index   = activeIndex + 1;
  244.         var tabHistory  = tabSession/*.slice(0)*/; // the entire rest of our "session-array" is tab history
  245.  
  246.         var frameText = [];        
  247.         for (var i=0; i < tabHistory.length; i++) {
  248.             var history = tabHistory[i].split(this.D[1]);
  249.             var entry = { url: history[1], scroll:history[0] };
  250.             
  251.             // active index - Session Saver does not postdata and frames for session history
  252.             if (i == activeIndex) {
  253.                 // frames
  254.                 if (frameData) {
  255.                     entry.children = [];
  256.                     var frameData = frameData.split(':');
  257.                     var textKeys ={'i':"input",'a':"textarea"};
  258.                     for (var f = 0; f < frameData.length; f++) {
  259.                         frameData[f]=frameData[f].split(",");
  260.                         var url = unescape(frameData[f][0]);
  261.                         var id = unescape(frameData[f][3]);
  262.                         var name = (frameData[f].length>4)?unescape(frameData[f][4]):id;
  263.                         var scroll = parseInt(frameData[f][1]) + "," + parseInt(frameData[f][2]);
  264.                         var text = (frameData[f].length>5 && frameData[f][5]!='')?unescape(frameData[f][5]).split(" "):null;
  265.                         var postDataFrame = (frameData[f].length>6 && frameData[f][6]!='')?unescape(frameData[f][6]):null;                        
  266.                         if (text && text.length>0) { 
  267.                             var t, key, textObj={}; 
  268.                             while ((t=text.shift())) key=textKeys[t.charAt(0)], textObj[key] = t.slice(1); 
  269.                             text = (textObj.input?textObj.input:"") + ((textObj.input && textObj.textarea)?":":"") + (textObj.textarea?textObj.textarea:""); 
  270.                             if (text) frameText.push(text);
  271.                         }
  272.                         
  273.                         var child = { url: url, scroll: scroll };
  274.                         if (postData) child.postData = postDataFrame;
  275.                         entry.children.push(child);
  276.                     }
  277.                 }
  278.                     
  279.                 // postdata
  280.                 if (postData) {
  281.                     entry.postdata_b64 = btoa(postData);
  282.                 }
  283.             }
  284.             
  285.             tabData.entries.push(entry);
  286.         }
  287.         
  288.         var textData = "";
  289.         if (areaData) areaData = areaData.split(":");
  290.         if (inputData) {
  291.             inputData = inputData.split(":");
  292.             if (areaData) inputData = inputData.concat(areaData);
  293.         }
  294.         else inputData = areaData;
  295.         if (inputData) {
  296.             for (var i=0; i<inputData.length; i++) {
  297.                 var text = inputData[i].split(",,");
  298.                 if (text[0] && text[1]) textData = textData + ((textData)?" ":"") + text[1] + "=" + text[0];
  299.             }
  300.         }
  301.         if (frameText) {
  302.             // form text for frames is stored with parent but tagged with frame number
  303.             for (var i=0; i<frameText.length; i++) {
  304.                 frameText[i] = frameText[i].split(":");
  305.                 for (var j=0; j<frameText[i].length; j++) {
  306.                     var text = frameText[i][j].split(",,");
  307.                     if (text[0] && text[1]) textData = textData + ((textData)?" ":"") + i + "|" + text[1] + "=" + text[0];
  308.                 }
  309.             }            
  310.         }
  311.         if (textData) tabData.text = textData;
  312.     },
  313.  
  314.     //
  315.     // The following code comes from the SessionSaver 0.2d extension originally coded by rue and Pike
  316.     // Modified by Morac to simplify and allow conversion to Session Manager format
  317.     //
  318.     
  319.     /*
  320.      * The following functions allow importing of current Session Saver data in preferences
  321.      */
  322.         
  323.     importSession: function () {
  324.         var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(Components.interfaces.nsIFilePicker);
  325.         var stream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
  326.         var streamIO = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
  327.         var validFile = false;
  328.             
  329.         fp.init(window, "Select a File", fp.modeOpen);
  330.         var ext = this.exportFileExt, mask = this.exportFileMask;
  331.         fp.appendFilter("SessionSaver Session",mask);
  332.         fp.defaultExtension = ext;
  333.         
  334.         if (fp.show() != fp.returnCancel) {
  335.             stream.init(fp.file, 0x01, 0444, null);
  336.             streamIO.init(stream);
  337.             var data = streamIO.read(stream.available());
  338.             streamIO.close(); stream.close();
  339.             this.findValidSession(data, true);
  340.         }
  341.     },
  342.     
  343.     findValidSession: function(data, shouldConvert) {
  344.         // convert and \r \r\n to \n so that we can handle new lines.  Note postdata will also be converted so 
  345.         // we need to take that into account
  346.         data = data.replace(/\r\n?/g, "\n");
  347.         var resArrayAll = data.split("\n"), res, resultHash = {}, extraLines = "", lastHash;
  348.         while ((res=resArrayAll.shift()) != null ) {
  349.             var lineParse = res.match(/^([s|c|i|a|b] .+)   (.+)/m);
  350.             if (lineParse) {
  351.                 resultHash[lineParse[1]] = lineParse[2];
  352.                 if (lastHash && extraLines) resultHash[lastHash] = resultHash[lastHash] + extraLines;
  353.                 extraLines = ""; 
  354.                 lastHash = lineParse[1];
  355.             }
  356.             else extraLines = extraLines + this.getEOL() + res;
  357.         }
  358.         var client={};
  359.         var d =new Date(), curDate =(d.getMonth()+1)+"."+d.getDate()+"."+((d.getFullYear()+"").slice(2));
  360.         var m;
  361.         var s2Prefix=this.prefBranch+this.prefBranchStatic+"Main-Session_From_Archive_("+curDate+")."; // -> Main-Session From Archive (10.25.05)
  362.         for (var n in resultHash) {
  363.             var keyPair = n.match(/^([^ ]) ([^ ]+)/); if (!keyPair) {continue;} else var key=keyPair[1], name=keyPair[2];
  364.             switch(key) {
  365.                 case "s": 
  366.                     if (name.indexOf(this.prefBranch + this.prefBranchWindows) == 0) {
  367.                         name = name.substring(this.prefBranch.length + this.prefBranchWindows.length);
  368.                     }
  369.                     client[s2Prefix+name] = resultHash[n]; 
  370.                     break;
  371.                 case "c": 
  372.                     client[name] = resultHash[n]; 
  373.                     break;   
  374.             }
  375.         }
  376.         var zorderRe = /^(.*)\.zorder$/i, zei, zHash={asArray:[],asName:{}}; // [******. hehe -rue]
  377.         for (m in client) {  
  378.             if (zei=m.match(zorderRe)) { 
  379.                 var name=zei[1], mName = name.replace(this.prefBranch+this.prefBranchStatic,""); 
  380.                 var mName=mName.replace(/_/g," "); 
  381.                 zHash.asArray.push(mName),zHash.asName[name]=mName; 
  382.             }   
  383.         } 
  384.  
  385.         if (shouldConvert) {
  386.             var sessionCnt = zHash.asArray.length;
  387.             if (sessionCnt==0) return this._prompt.alert(this.gSessionManager._string("ss_none")); 
  388.             this.convertSession(client,zHash);
  389.         }
  390.         
  391.         return zHash;
  392.     },
  393.  
  394.     /*
  395.      * The following functions allow exporting of current Session Saver data in preferences
  396.      */
  397.     createSessionData: function() { // returns a single string, of the relevant prefs
  398.         var d=new Date(),  curMonth=d.getMonth()+1,  curDate=(d.getMonth()+1)+"."+d.getDate()+"."+((d.getFullYear()+"").slice(2));
  399.         var currName = this.prefBranch+this.prefBranchStatic+"default_("+curDate+")";
  400.         var prefArrayAll = [];
  401.         var prefConverter = { keyed:{}, hashed:{a:Components.interfaces.nsIPrefBranch.PREF_INT, b:Components.interfaces.nsIPrefBranch.PREF_BOOL, c:Components.interfaces.nsIPrefBranch.PREF_STRING}, retrieve:{a:"getIntPref",b:"getBoolPref",c:"getCharPref"} };
  402.         var h = prefConverter.hashed; 
  403.         for (var n in h) prefConverter.keyed[h[n]]=n; 
  404.         var prefsToPush = ["sessionsaver.static.","sessionsaver.windows."];
  405.         var push; 
  406.         while ((push=prefsToPush.shift())) {
  407.             var prefName, childArray = this.rootBranch.getChildList(push, {}); // array of pref-names, off this particular branch
  408.             while ((prefName=childArray.shift())) {
  409.                 if (prefName.match(/^sessionsaver\.static\.sync_backup\./i)) {continue;}
  410.                 var key = prefConverter.keyed[ this.rootBranch.getPrefType(prefName) ];
  411.                 var getPrefAsType = prefConverter.retrieve[key];
  412.                 prefArrayAll.push((prefName.match(/^sessionsaver\.static/i)?key:"s")+" "+prefName+"   "+this.rootBranch[getPrefAsType](prefName)); }
  413.         }
  414.         return prefArrayAll.join("\n");
  415.     },
  416.         
  417.     exportSession: function() {
  418.         var d=new Date(),  curMonth=d.getMonth()+1,  curDate=(d.getMonth()+1)+"."+d.getDate()+"."+((d.getFullYear()+"").slice(2));
  419.         var data = this.createSessionData();
  420.         if (!data) {
  421.             alert("There wasn't any Session Saver session-data to export!");
  422.             return false;
  423.         }
  424.         var zHash = this.findValidSession(data,false);
  425.         // make sure all newlines are set to OS default.
  426.         data = data.replace(/\r\n?/g, "\n");
  427.         data = data.replace(/\n/g, this.getEOL());
  428.         var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(Components.interfaces.nsIFilePicker);
  429.         var filestream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
  430.         var buffered   = Components.classes["@mozilla.org/network/buffered-output-stream;1"].createInstance(Components.interfaces.nsIBufferedOutputStream);
  431.         var binstream  = Components.classes["@mozilla.org/binaryoutputstream;1"].createInstance(Components.interfaces.nsIBinaryOutputStream); 
  432.         
  433.         fp.init(window, "Select a File", fp.modeSave);
  434.         var ext = this.exportFileExt, mask = this.exportFileMask;
  435.         fp.appendFilter("SessionSaver Session",mask);
  436.         fp.defaultExtension = ext;
  437.         var sessionCnt  = zHash.asArray.length;
  438.         var wordSpacer  = (curMonth >  9 && sessionCnt >  9) ? "":" ";
  439.         var prefsTxt    = (curMonth < 10 && sessionCnt < 10) ? "+prefs":"+pref";
  440.         if (sessionCnt > 1)
  441.             var mainTxt = "("+sessionCnt+" sessions"+wordSpacer+prefsTxt+")"+" "+curDate; // "exports":"export" -> "sessions":"session"
  442.         else
  443.             mainTxt = zHash.asArray[0].slice(0,27); //31); //12)
  444.         fp.defaultString  = mainTxt+"."+ext;
  445.     
  446.         if (fp.show() != fp.returnCancel) {
  447.             if (fp.file.exists()) fp.file.remove(true);
  448.             if (fp.file.exists()) {
  449.                 alert("The Export failed: try using a unique, or new, filename.");
  450.                 return false;
  451.             }
  452.             fp.file.create(fp.file.NORMAL_FILE_TYPE, 0666);
  453.     
  454.             filestream.init(fp.file, 0x02 | 0x08, 0644, 0);
  455.             buffered.init(filestream, 64 * 1024);
  456.             binstream.setOutputStream(buffered);
  457.             binstream.writeBytes(data,data.length);
  458.             binstream.close(), buffered.close();
  459.             filestream.close(); 
  460.         }
  461.         return true;
  462.     }
  463. }
  464.  
  465. /********************************************************************************************************************
  466.  *  Routines to convert from Tab Mix Plus session format to Session Manager format.
  467.  *  Original code by Morac except where indicated otherwise
  468.  ********************************************************************************************************************/
  469.  
  470. var gConvertTMPSession = {
  471.     
  472.     sessionList: null,
  473.  
  474.     init: function() {
  475.         this.RDFService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
  476.         this.RDFResource = Components.interfaces.nsIRDFResource;
  477.         
  478.         var windowMediator  = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator);
  479.         var chromeWin = windowMediator.getMostRecentWindow("navigator:browser");
  480.         this.gSessionManager = chromeWin.gSessionManager;
  481.  
  482.         // if encryption, force master password and exit if not entered
  483.         try {
  484.             if (this.gSessionManager.mPref_encrypt_sessions) this.gSessionManager.mSecretDecoderRing.encryptString("");
  485.         }
  486.         catch(ex) {
  487.             this.gSessionManager.cryptError(gSessionManager._string("encrypt_fail2"));
  488.             this.RDFService = null;
  489.             this.RDFResource = null;
  490.             this.gSessionManager = null;
  491.             return;
  492.         }
  493.         
  494.         if (!chromeWin.TMP_SessionStore) {
  495.             this._prompt.alert(null, this.gSessionManager._string("sessionManager"), this.gSessionManager._string("tmp_no_install"));
  496.             return;
  497.         }
  498.         else {
  499.             this.SessionManager = chromeWin.SessionManager;
  500.             this.convertSession = chromeWin.convertSession;
  501.             this.gSessionPath = chromeWin.gSessionPath;
  502.             if (!this.convertFile()) {
  503.                 if (!this.confirm(this.gSessionManager._string("tmp_no_default"))) {
  504.                     this.pickFile();
  505.                 }
  506.             }
  507.         }
  508.  
  509.         this.RDFService = null;
  510.         this.RDFResource = null;
  511.         this.gSessionManager = null;
  512.     },
  513.         
  514.     //
  515.     // The following code comes from the Tab Mix Plus extension originally coded by onemen
  516.     // Modified by Morac to allow user to choose which sessions to convert
  517.     // 
  518.     // Note: These functions call Tab Mix Plus functions and as such are dependent on TMP
  519.     //
  520.     
  521.     // Not currently used
  522.     pickFile: function() {
  523.         var file = null;
  524.         const nsIFilePicker = Components.interfaces.nsIFilePicker;
  525.         var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
  526.         fp.init(window, "Select session.rdf file to convert", nsIFilePicker.modeOpen);
  527.         fp.defaultString="session.rdf";
  528.         fp.appendFilter("RDF Files", "*.rdf");
  529.         fp.appendFilter("Session Files", "*session*.*");
  530.         fp.appendFilters(nsIFilePicker.filterText | nsIFilePicker.filterAll);
  531.  
  532.         if (fp.show() != nsIFilePicker.returnOK)
  533.             return;
  534.  
  535.         file = fp.fileURL.spec;
  536.         try {
  537.             if (!this.convertFile(file)) {
  538.                 this._prompt.alert(null, this.gSessionManager._string("sessionManager"), this.gSessionManager._string("ss_none"));
  539.             }
  540.         } catch (ex) {
  541.             dump(ex);
  542.         }
  543.     },
  544.     
  545.     get _prompt() {
  546.         return Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
  547.                                      .getService(Components.interfaces.nsIPromptService);
  548.     },
  549.  
  550.     confirm: function (aMsg) {
  551.         var promptService = this._prompt;
  552.         return promptService.confirmEx(null,
  553.                                     this.gSessionManager._string("sessionManager"),
  554.                                     aMsg,
  555.                                     (promptService.BUTTON_TITLE_YES * promptService.BUTTON_POS_0)
  556.                                     + (promptService.BUTTON_TITLE_NO * promptService.BUTTON_POS_1),
  557.                                     null, null, null, null, {});
  558.     },
  559.     
  560.     convertFile: function (aFileUri) {
  561.         var sessions;
  562.         var tmpDATASource;
  563.         if (aFileUri) {
  564.             try {
  565.                 tmpDATASource = this.SessionManager.DATASource;
  566.                 this.SessionManager.DATASource = this.RDFService.GetDataSourceBlocking(aFileUri);
  567.                 sessions = this.SessionManager.getSessionList();
  568.             } catch (e) { // corrupted session.rdf
  569.                 this.SessionManager.DATASource = tmpDATASource;
  570.                 dump(e);
  571.             }
  572.         }
  573.         else
  574.             sessions = this.SessionManager.getSessionList();
  575.  
  576.         var msg;
  577.         if (!sessions) {
  578.             if (tmpDATASource) this.SessionManager.DATASource = tmpDATASource;
  579.             return false;
  580.         }
  581.         var rv = 0;
  582.         if(this.SessionManager.nodeHasArc("rdf:gSessionManager", "status")) {
  583.             rv = this.confirm(this.gSessionManager._string("ss_convert_again"));
  584.         }
  585.         else {
  586.             this.SessionManager.setLiteral("rdf:gSessionManager", "status", "converted");
  587.             this.SessionManager.saveStateDelayed();
  588.         }
  589.         if (rv == 0) {
  590.             try {
  591.                 this.doConvert(sessions);
  592.             }
  593.             catch(ex) { dump(ex) };
  594.         }
  595.  
  596.         if (tmpDATASource) this.SessionManager.DATASource = tmpDATASource;
  597.             
  598.         return true;
  599.     },
  600.  
  601.     doConvert: function (sessions) {
  602.         var sessionsPath = sessions.path.push(this.gSessionPath[3]);
  603.         var sessionsName = sessions.list.push("Crashed Session");
  604.         var _count = 0;
  605.         
  606.         this.sessionList = [];
  607.         for (var i in sessions.list) {
  608.             var nameExt = this.SessionManager.getLiteralValue(sessions.path[i], "nameExt");
  609.             if (nameExt) {
  610.                 var winCount="", tabCount="";
  611.                 // get window and tab counts
  612.                 if (/(((\d+) W, )?(\d+) T)/m.test(nameExt)) {
  613.                     winCount = RegExp.$3 ? RegExp.$3 : "1";
  614.                     tabCount = RegExp.$4 ? RegExp.$4 : "";
  615.                 }
  616.         
  617.                 var sessionListItem = { name: unescape(sessions.list[i]), fileName: sessions.list[i], autosave: false, windows: winCount, tabs: tabCount, group: "[Tabmix]" };
  618.                 this.sessionList.push(sessionListItem);
  619.             }
  620.         }
  621.         var sessionsToConvert = this.gSessionManager.selectSession(this.gSessionManager._string("ss_select"), 
  622.                                                                    this.gSessionManager._string("ss_convert"), 
  623.                                                                    { multiSelect: true }, 
  624.                                                                    function() { return gConvertTMPSession.sessionList;}
  625.                                                                   );   
  626.         delete this.sessionList;
  627.         if (!sessionsToConvert) return;
  628.         sessionsToConvert = sessionsToConvert.split("\n");
  629.         var convert = [sessions.list.length];
  630.         for (var i = 0; i < sessions.list.length; i++ ) {
  631.             convert[i] =  (sessionsToConvert.indexOf(sessions.list[i]) != -1)
  632.         }
  633.  
  634.         for (var i = 0; i < sessions.path.length; i++ ) {
  635.             if (!convert[i]) continue;
  636.             var sessionState = this.convertSession.getSessionState(sessions.path[i]);
  637.  
  638.             // get timestamp from nameExt property
  639.             var dateString = "", fileDate, winCount="0", tabCount="0";
  640.             var nameExt = this.SessionManager.getLiteralValue(sessions.path[i], "nameExt");
  641.             if (nameExt) {
  642.                 var date = nameExt.substr(nameExt.length - 20, 10);
  643.                 var time = nameExt.substr(nameExt.length - 9, 8);
  644.                 fileDate = " (" + date.split("/").join("-") + ")";
  645.                 dateString = " (" + date.split("/").join("-") + " " + time.substr(0, time.length - 3) + ")";
  646.                 var _time = time.split(":");
  647.                 var timestamp = new Date(date).valueOf() + 3600*_time[0] + 60*_time[1] + 1*_time[2];
  648.                 
  649.                 // get window and tab counts
  650.                 if (/(((\d+) W, )?(\d+) T)/m.test(nameExt)) {
  651.                     winCount = RegExp.$3 ? RegExp.$3 : "1";
  652.                     tabCount = RegExp.$4 ? RegExp.$4 : "";
  653.                 }
  654.             }
  655.             var sessionName = unescape(sessions.list[i]);
  656.             var name = "[ Tabmix ] " + sessionName + dateString;
  657.             var fileName = this.gSessionManager.makeFileName("Tabmix - " + sessionName + fileDate);
  658.  
  659.             _count += this.save(sessionState, timestamp, name, fileName, winCount, tabCount);
  660.         }
  661.  
  662.         var msg;
  663.         if (_count == 0) {
  664.             this._prompt.alert(null, this.gSessionManager._string("sessionManager"), this.gSessionManager._string("tmp_unable"));
  665.             return;
  666.         }
  667.         var msg = (_count > 1)?(_count + " " + this.gSessionManager._string("tmp_many")):this.gSessionManager._string("tmp_one");
  668.         this._prompt.alert(null, this.gSessionManager._string("sessionManager"), msg);
  669.     },
  670.     
  671.     save: function (aSession, aTimestamp, aName, aFileName, winCount, tabCount) {
  672.         if (aSession.windows.length == 0)
  673.             return false;
  674.  
  675.         if (!aSession.session)
  676.             aSession.session = { state:"stop" };
  677.         var oState = "[SessionManager v2]\nname=" + aName + "\ntimestamp=" + aTimestamp + "\nautosave=false\tcount=" +
  678.                      winCount + "/" + tabCount + "\tgroup=[Tabmix]\n" + 
  679.                      this.gSessionManager.decryptEncryptByPreference(this.gSessionManager.JSON_encode(aSession));
  680.         var file = this.gSessionManager.getSessionDir(gSessionManager.makeFileName(aName));
  681.         try {
  682.             var file = this.gSessionManager.getSessionDir(aFileName, true);
  683.             this.gSessionManager.writeFile(file, oState);
  684.         }
  685.         catch (ex) {
  686.             dump(ex);
  687.             return false;
  688.         }
  689.         return true;
  690.     }
  691. }
  692.